//
// Created by lenovo on 2024/1/17.
//
#include "Lexer.h"
#include <utility>
#include <vector>
#include <stack>

#include <iostream>
using namespace std ;

class ArgvExtractor{
public :
    std::vector<token*> tokens ;
    std::vector<Evaluable*> _argv ;
    std::vector<std::vector<token*> > tv ;
    std::vector< std::set<std::string> >* priority {nullptr} ;//定义了运算符的优先级
    std::map< std::string , Functions::iFunction*>* _identified_funcs {nullptr};//需要用到的函数

    explicit ArgvExtractor(std::vector<token*> t ,
                           std::map<std::string ,Functions::iFunction*>* _map,
                           std::vector<std::set<std::string> >* prio = &Priority::OptPrio)
                           : tokens(std::move(t)) , priority(prio) , _identified_funcs(_map) {}

    std::vector<Evaluable*> result(){
        if (not _done)
            extract();
        _done =  true ;
        return _argv ;
    } ;

    bool _done {false};


    void extractTokenArgv(){

        std::vector<token*> subToken ;
        int _bracket_cnt = 0 ;

        for (auto t : tokens){
            if (t->type != token::DOT){
                if (t->type == token::LBRACKET)
                    _bracket_cnt ++ ;
                else if (t->type == token::RBRACKET)
                    _bracket_cnt -- ;
                subToken.push_back(t);
                continue ;
            }

            //DOT
            if (subToken.empty()){
                throw std::logic_error("Dot in a Wrong Place");
            }
            if (_bracket_cnt == 0){
                tv.push_back(subToken);
                subToken.clear() ;
            }else{
                subToken.push_back(t);
            }

        }

        if (not subToken.empty())
            tv.push_back(subToken);
    };



    void loadEArgv(){
        for (const auto& v : tv){
            Lexer lx(v , this->_identified_funcs , this->priority);
            _argv.push_back(lx.root());
        }
    }



    void extract(){
        extractTokenArgv();
        loadEArgv();
    }

};


void Lexer::funcExtract(){
    int i = 0 ;

    while(i < this->tokens.size()){
        auto t = this->tokens[i];

        if ( t->type != token::FUNCTION){
            i ++ ;
            continue ;
        }

        //ELSE
        //TokenType::Function
        int j = i + 1 ;
        auto cur = this->tokens[j];
        if (cur->type != token::LBRACKET)
            throw logic_error("Invalid Syntax while Calling a Function");
        //ELSE
        int _bracket_cnt = 1 ;
        std::vector<token*> subToken ;
        j ++ ;

        while ( j < this->tokens.size()){
            cur = this->tokens[j] ;
            if (cur->type == token::LBRACKET)
                _bracket_cnt ++ ;
            else if (cur->type == token::RBRACKET)
                _bracket_cnt -- ;

            if (_bracket_cnt == 0)
                break ;

            subToken.push_back(cur);
            j ++ ;

        }
//        cout << "token-argv EXTRACTing Finished" << endl ;

        this->tokens.erase(
                this->tokens.begin() + i ,
                this->tokens.begin() + j + 1
                );
        ArgvExtractor ave(subToken , this->_identified_funcs , this->priority);

//        cout << "ArgvExtractor LOADING Finished" << endl ;

        auto f = new Funcs;
        f->FuncType = ((Funcs*)t->base)->FuncType;
        f->_argv = ave.result() ;
//        cout << "EVALUABLE Function Argv LOADING Finished" << endl ;
        f->_identified_funcs = this->_identified_funcs;

        this->tokens.insert(
                this->tokens.begin() + i ,
                new token(
                        token::NUMBER,
                        f
                        )
                );
//        cout << "Func-Token Floding FINISHED" << endl ;

        i ++ ;
    }

}